

#### 形式参数和实际参数

# 定义的一个函数：计算2个数的和
def isum(a, b):
    # a,b 是形参
    if isinstance(a, str):
        return "变量不能为str类型"
    a = 100
    return a+b

a = 1
b = 2
print(a, b)
isum(a, b)
print(a, b)
# a,b是实际的参数


#### 参数个数
# 参数的个数可以是0个或1个或1个以上


#### 参数的分类

### 必选参数
# 特点：调用的时候，是必须添加的(否则会报错)
#       传递的时候，是按照顺序赋值
def isum(a, b):
    return a+b

print(isum(1,2))
print(isum(b=1,a=2))

# TypeError: isum() missing 1 required positional argument: 'b'
# print(isum(b=1))
# print(isum(1))


### 默认参数/关键字参数
# 特点：参数会有一个默认值
#     在调用的时候可以不用为这个参数赋值

def ipop(mylist, index=-1):
    mylist.pop(index)
    return mylist

fruits = ['apple', 'orange', 'pear', 'banana']
print(ipop(fruits))
print(ipop(fruits, 0))



#### 调用的角度：位置参数与关键字参数
ipop(mylist=[1,2,3,4], index=0)    # 关键字调用
ipop(index=0, mylist=[1,2,3,4])    # 关键字调用
ipop([1,2,3,4], 0)                 # 位置调用



### 注意：
# 位置参数在前，默认参数在后
# SyntaxError: non-default argument follows default argument
# def ipop(index=-1, mylist):
#     mylist.pop(index)
#     return mylist



### 不定长参数（可变参数）
# *args:args接收到之后是一个元组（tuple）
# **kwargs: kwargs接收到之后是一个字典(dict)

def mysum(*args):
    # tuple
    print(type(args), args)

mysum(1,2,3,4,5,6,7)



def mysum(**kwargs):
    # dict
    print(type(kwargs), kwargs)

# SyntaxError: keyword argument repeated
# mysum(a=1, b=2, c=3, a=5)

mysum(a=1, b=2, c=3)



#### 参数定义先后
### 常用组合
# mysun(必选参数, *args, 默认参数, **kargs):
def mysun(a, *args, b=1,  **kwargs):
    print(a, b, args, kwargs)


mysun(1, 2, 3, 4, b=2, c=1, d=3)
mysun(1, 2, 3, 4, c=1, d=3, b=2)

# 1 => a
# 2, 3, 4 => args
# b=1 => b
# c=1, d=3 => kwargs


#### 参数的packing和uppacking

def mysum(a,b,c,d):
    print(a,b,c,d)

li = [1,2,3,4]
mysum(li[0], li[1], li[2], li[3])
# unpacking
mysum(*li)


def mysum(a,b,c,d):
    print(a,b,c,d)

li = {'a':1,'b':2,'c':3,'d':4}
mysum(li['a'],li['b'],li['c'],li['d'])
# unpacking
mysum(*li)
mysum(**li)

